const sourceMap = require('source-map')
const fs = require('fs')
const log = require("@hl-cli/log")
const chalk = require('chalk')
const pathExists = require('path-exists').sync;
const inquirer = require('inquirer')
const { spinnerStart } = require("@hl-cli/utlis");

function exec() {
    const sourcePath = process.env.SOURCE;
    if (checkPath(sourcePath)) {
        const promptList = [{
                type: 'input',
                message: '请输入报错的行:',
                name: 'line',
                validate,
                filter: function(v) {
                    return v;
                },
            },
            {
                type: 'input',
                message: '请输入报错的列:',
                name: 'column',
                validate,
                filter: function(v) {
                    return v;
                },
            },
        ]
        inquirer.prompt(promptList).then(res => {
            analyse(res, sourcePath)
        })
    }
}

function validate(v) {
    const done = this.async();
    setTimeout(function() {
        if (!/^\d+$/.test(v)) {
            done(`请输入整数型数字`);
            return;
        }
        done(null, true);
    }, 0);
}

function checkPath(sourcePath) {
    if (!sourcePath) {
        log.warn(chalk.red('.map文件路径不能为空'));
        return false
    } else if (!sourcePath.endsWith('.map')) {
        log.warn(chalk.red('文件后缀必须是.map'));
        return false
    } else if (!pathExists(sourcePath)) {
        log.warn(chalk.red(sourcePath + '，文件不存在'));
        return false
    }
    return true
}


function fixPath(filepath) {
    return filepath.replace(/\.[\.\/]+/g, '')
}

async function analyse(ages, sourcePath) {
    let spinner = spinnerStart('代码分析中，请稍后...');
    try {
        let sourcesPathMap = {}
        let sourceMapContent = fs.readFileSync(sourcePath, 'utf-8')
        let fileObj = JSON.parse(sourceMapContent)
        let sources = fileObj.sources
        sources.map(item => {
            sourcesPathMap[fixPath(item)] = item
        })
        let findPos = {
            line: Number(ages.line),
            column: Number(ages.column),
        }
        let consumer = await new sourceMap.SourceMapConsumer(sourceMapContent);
        let result = consumer.originalPositionFor(findPos);
        let originSource = sourcesPathMap[result.source];
        let sourcesContent = fileObj.sourcesContent[sources.indexOf(originSource)];
        let sourcesContentArr = sourcesContent.split('\n');
        result.sourcesContentMap = sourcesContentArr;
        log.info('\n分析完毕')
        log.info(`${chalk.yellow('  输入的文件: ' + sourcePath)}`)
        log.info(`${chalk.yellow('  输入的行: ' + ages.line)}`)
        log.info(`${chalk.yellow('  输入的列: ' + ages.column)}`)
        log.info(`${chalk.green('  分析结果如下: ')}`)
            // 防止越界
        let line = result.line
        if (line < 4) {
            let x = 4 - line
            for (let i = 0; i < x; i++) {
                result.sourcesContentMap.unshift('防止越界替补空数据')
            }
            line = 4
        }
        result.sourcesContentMap = result.sourcesContentMap.slice(line - 4, line + 3)
        result.sourcesContentMap.forEach((element, i) => {
            if (i === 3) {
                log.info(`${chalk.red('  ' + element)}`)
            } else {
                log.info(`${chalk.green('  ' + element)}`)
            }
        })
        log.info(`${chalk.green('  错误对应的源码信息:')}`)
        console.log(result)
    } catch (e) {
        log.error(chalk.red((e.message)));
        log.error(chalk.red('\n分析失败，请检查文件是否正确，行列信息是否正确'));
        log.warn(`${chalk.yellow('  文件路径: ' + sourcePath)}`)
        log.warn(`${chalk.yellow('  输入的行: ' + ages.line)}`)
        log.warn(`${chalk.yellow('  输入的列: ' + ages.column)}`)
    } finally {
        spinner.stop(true);
    }
}

module.exports = exec;